package com.ruoyi.system.api.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.AMapUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.LngLat;
import com.ruoyi.system.api.ResponseWithData;
import com.ruoyi.system.api.domain.*;
import com.ruoyi.system.api.mapper.*;
import com.ruoyi.system.api.service.CcService;
import com.ruoyi.system.api.service.IServiceInstrumentService;
import com.ruoyi.system.api.service.LocationService;
import com.ruoyi.system.api.service.PokeRequestServe;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 服务派单涉及到的仪器信息 (数据来源于CC端主动调用，和服务派单主信息一起入库)Service业务层处理
 *
 * @author shihx
 * @date 2020-03-05
 */
@Service
public class ServiceInstrumentServiceImpl implements IServiceInstrumentService {
    @Autowired
    private ServiceInstrumentMapper serviceInstrumentMapper;

    @Autowired
    private ServiceNoticeMapper serviceNoticeMapper;

    @Autowired
    private InstrumentInfoMapper instrumentInfoMapper;

    @Autowired
    private StInfoUpdateMapper stInfoUpdateMapper;

    @Autowired
    private CcService ccService;

    @Autowired
    private ConfigurationMapper configurationMapper;

    @Autowired
    private LocationService locationService;

    @Autowired
    private PokeRequestServe pokeRequestServe;
    @Autowired
    private Global global;

    /**
     * 查询服务派单涉及到的仪器信息 (数据来源于CC端主动调用，和服务派单主信息一起入库)
     *
     * @param id 服务派单涉及到的仪器信息 (数据来源于CC端主动调用，和服务派单主信息一起入库)ID
     * @return 服务派单涉及到的仪器信息 (数据来源于CC端主动调用，和服务派单主信息一起入库)
     */
    @Override
    public ServiceInstrument selectServiceInstrumentById(Long id) {
        return serviceInstrumentMapper.selectServiceInstrumentById(id);
    }

    /**
     * 查询服务派单涉及到的仪器信息 (数据来源于CC端主动调用，和服务派单主信息一起入库)列表
     *
     * @param serviceInstrument 服务派单涉及到的仪器信息 (数据来源于CC端主动调用，和服务派单主信息一起入库)
     * @return 服务派单涉及到的仪器信息 (数据来源于CC端主动调用，和服务派单主信息一起入库)
     */
    @Override
    public List<ServiceInstrument> selectServiceInstrumentList(ServiceInstrument serviceInstrument) {
         List<ServiceInstrument> serviceInstrumentList = serviceInstrumentMapper.selectServiceInstrumentList(serviceInstrument);
         for(ServiceInstrument serviceInstrument1:serviceInstrumentList){
             ServiceNotice serviceNotice = serviceNoticeMapper.selectServiceNoticeById(serviceInstrument1.getServiceNoticeId());
             serviceInstrument1.setHomeAddress(serviceNotice.getHomeAddress());
             serviceInstrument1.setAccoutFseName(serviceNotice.getAccoutfseName());
             if(!StringUtils.isEmpty(serviceInstrument1.getInstrumentId())){
                 String cfda = getInstrumentCfda(serviceInstrument1.getInstrumentId());
                 serviceInstrument1.setCfda(cfda);
             }
         }
         return serviceInstrumentList;
    }



    /**
     * 新增服务派单涉及到的仪器信息 (数据来源于CC端主动调用，和服务派单主信息一起入库)
     *
     * @param serviceInstrument 服务派单涉及到的仪器信息 (数据来源于CC端主动调用，和服务派单主信息一起入库)
     * @return 结果
     */
    @Override
    public int insertServiceInstrument(ServiceInstrument serviceInstrument) {
        return serviceInstrumentMapper.insertServiceInstrument(serviceInstrument);
    }

    /**
     * 修改服务派单涉及到的仪器信息 (数据来源于CC端主动调用，和服务派单主信息一起入库)
     *
     * @param serviceInstrument 服务派单涉及到的仪器信息 (数据来源于CC端主动调用，和服务派单主信息一起入库)
     * @return 结果
     */
    @Override
    public int updateServiceInstrument(ServiceInstrument serviceInstrument) {
        return serviceInstrumentMapper.updateServiceInstrument(serviceInstrument);
    }

    /**
     * 删除服务派单涉及到的仪器信息 (数据来源于CC端主动调用，和服务派单主信息一起入库)对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteServiceInstrumentByIds(String ids) {
        return serviceInstrumentMapper.deleteServiceInstrumentByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除服务派单涉及到的仪器信息 (数据来源于CC端主动调用，和服务派单主信息一起入库)信息
     *
     * @param id 服务派单涉及到的仪器信息 (数据来源于CC端主动调用，和服务派单主信息一起入库)ID
     * @return 结果
     */
    @Override
    public int deleteServiceInstrumentById(Long id) {
        return serviceInstrumentMapper.deleteServiceInstrumentById(id);
    }

    @Override
    public ResponseWithData<?> setPartAccountFSE(String ServiceNoticeId, String ServiceNo, String TeamleaderId, String AccoutfseId, String AccoutfseName) {

        /** 查询仪器信息 */
        ServiceInstrument serviceInstrument = new ServiceInstrument();
        serviceInstrument.setServiceNoticeId(Long.parseLong(ServiceNoticeId));
        List<ServiceInstrument> siList = serviceInstrumentMapper.selectServiceInstrumentList(serviceInstrument);

        if (siList != null && siList.size() > 0) {

            /** 调用CC端仪器指定FSE的接口 */
            JSONObject jsonObject = ccService.setPartAccountFSE(TeamleaderId, ServiceNo, AccoutfseId, siList.get(0).getInstrumentId());

            if ("200".equals(jsonObject.getString("code"))) {
                /** 更新服务单主表 */
                ServiceNotice serviceNotice = new ServiceNotice();
                serviceNotice.setId(Long.parseLong(ServiceNoticeId));
                serviceNotice.setAccoutfseId(AccoutfseId);
                serviceNotice.setAccoutfseName(AccoutfseName);
                serviceNoticeMapper.updateServiceNoticeAccoutfse(serviceNotice);

                /** 更新仪器表 */
                InstrumentInfo instrumentInfo = new InstrumentInfo();
                instrumentInfo.setAccoutfseId(AccoutfseId);
                instrumentInfo.setAccoutfseName(AccoutfseName);
                instrumentInfo.setInstrumentId(siList.get(0).getInstrumentId());
                instrumentInfoMapper.updateInstrumentInfoAccoutfse(instrumentInfo);

                return new ResponseWithData<>().success().msg("设置成功").code(200);
            } else {
                return new ResponseWithData<>().success().msg("设置失败").code(202);
            }

        } else {
            return new ResponseWithData<>().success().msg("操作失败").code(201);
        }
    }

    @Override
    public ResponseWithData<?> getInstrumentList(String CustomerName, String serialNo, String Div, String bu,String starttime,String endtime) throws Exception {
        JSONObject jsonObject = ccService.getInstrumentList(CustomerName, serialNo, Div, bu,starttime,endtime);
        return new ResponseWithData<>().success(jsonObject).msg("查询成功").code(200);
    }

    @Override
    public ResponseWithData<?> checkSerialNumber(String ServiceNoticeId, String serialNumber) {
        ServiceInstrument serviceInstrument = new ServiceInstrument();
        serviceInstrument.setServiceNoticeId(Long.parseLong(ServiceNoticeId));
        List<ServiceInstrument> siList = serviceInstrumentMapper.selectServiceInstrumentList(serviceInstrument);
        if (siList != null && siList.size() > 0) {
            if (serialNumber.equals(siList.get(0).getInstrumentSerialNumber())) {
                return new ResponseWithData<>().success(siList.get(0)).msg("核对一致").code(200);
            }
        }
        return new ResponseWithData<>().error().msg("核对不一致").code(201);
    }

    @Override
    public ResponseWithData<?> bindingQrCode(String ServiceNoticeId, String QrCode, String EnginnerId) {
        ServiceInstrument serviceInstrument = new ServiceInstrument();
        serviceInstrument.setServiceNoticeId(Long.parseLong(ServiceNoticeId));
        List<ServiceInstrument> siList = serviceInstrumentMapper.selectServiceInstrumentList(serviceInstrument);
        if (siList != null && siList.size() > 0) {
            /** 调用CC端仪2.17绑定仪器条码接口 */
            JSONObject jsonObject = ccService.BindDeviceInfo(siList.get(0).getInstrumentId(), EnginnerId, QrCode);

            // 需要验证接口返回是否成功，如果成功更新数据库

            if ("200".equals(jsonObject.getString("code"))) {
                InstrumentInfo instrumentInfo = new InstrumentInfo();
                instrumentInfo.setInstrumentId(siList.get(0).getInstrumentId());
                instrumentInfo.setQrCode(QrCode);
                instrumentInfoMapper.updateInstrumentInfoAccoutfse(instrumentInfo);
                return new ResponseWithData<>().success().msg("绑定成功").code(200);
            } else {
                return new ResponseWithData<>().success().msg("绑定失败").code(202);
            }

        } else {
            return new ResponseWithData<>().success().msg("操作失败").code(201);
        }


    }

    @Override
    public ResponseWithData<?> updateApply(UpdateApply updateApply) {
        // 是否更改地址
        if (updateApply.isDizhi()) {
            String[] snos = updateApply.getServiceNo().split(",");
            for (int i = 0; i < snos.length; i++) {
                StInfoUpdate stInfoUpdate = new StInfoUpdate();
                stInfoUpdate.setRemarks(updateApply.getRemarks());
                stInfoUpdate.setEnginnerId(Long.parseLong(updateApply.getEnginnerId()));
                stInfoUpdate.setServiceNo(snos[i]);
                stInfoUpdate.setDelFlag("0");
                stInfoUpdate.setStatus(0L);
                stInfoUpdate.setCreateTime(new Date());
                stInfoUpdate.setParameter(updateApply.getParameter());
                // 信息修改申请的类型 1核对序列号 2地址变更 等...
                stInfoUpdate.setType(updateApply.getType());
                stInfoUpdateMapper.insertStInfoUpdate(stInfoUpdate);

                if ("1".equals(updateApply.getType())) {
                    // 更改核对序列号状态为已核对
                    ServiceNotice serviceNotice = new ServiceNotice();
                    serviceNotice.setServiceNo(snos[i]);
                    serviceNotice.setIsCheck("2");
                    serviceNoticeMapper.updateServiceNoticeByServiceNo(serviceNotice);
                }
                if (StringUtils.isEmpty(updateApply.getRemarks())) {
                    return new ResponseWithData<>().msg("操作成功").code(200);
                }
                /** 调用CC端接口 2.16信息修改申请 */
                JSONObject jsonObject = ccService.updateOrderInfo(updateApply.getEnginnerId(), snos[i], updateApply.getRemarks());
                if ("200".equals(jsonObject.getString("code"))) {
                    stInfoUpdate.setRequestId(Long.parseLong(jsonObject.getString("data")));
                    stInfoUpdateMapper.updateStInfoUpdate(stInfoUpdate);
                }
            }
        }
        // 是否更改经纬度
        if (updateApply.isJwd()) {
            String[] sids = updateApply.getServiceNoticeId().split(",");
            for (int i = 0; i < sids.length; i++) {
                List<InstrumentInfo> list = instrumentInfoMapper.getInstrumentInfoList(sids[i]);
                InstrumentInfo instrumentInfo = new InstrumentInfo();
                instrumentInfo.setId(list.get(0).getId());
                instrumentInfo.setLongitude(updateApply.getLongitude());
                instrumentInfo.setLatitude(updateApply.getLatitude());
                instrumentInfoMapper.updateInstrumentInfo(instrumentInfo);
            }
        }
        return new ResponseWithData<>().msg("操作成功").code(200);

    }


    public ResponseWithData<?> skipApply(UpdateApply updateApply) {
        // 是否更改地址
        if (updateApply.isDizhi()) {
            String[] snos = updateApply.getServiceNo().split(",");
            for (int i = 0; i < snos.length; i++) {
                StInfoUpdate stInfoUpdate = new StInfoUpdate();
                stInfoUpdate.setRemarks("fse 自动跳过....");
                stInfoUpdate.setEnginnerId(Long.parseLong(updateApply.getEnginnerId()));
                stInfoUpdate.setServiceNo(snos[i]);
                stInfoUpdate.setDelFlag("0");
                stInfoUpdate.setStatus(0L);
                stInfoUpdate.setCreateTime(new Date());
                stInfoUpdate.setParameter(updateApply.getParameter());
                // 信息修改申请的类型 1核对序列号 2地址变更 等...
                stInfoUpdate.setType("1");
                stInfoUpdateMapper.insertStInfoUpdate(stInfoUpdate);

                if ("1".equals(updateApply.getType())) {
                    // 更改核对序列号状态为已核对
                    ServiceNotice serviceNotice = new ServiceNotice();
                    serviceNotice.setServiceNo(snos[i]);
                    serviceNotice.setIsCheck("1");
                    serviceNoticeMapper.updateServiceNoticeByServiceNo(serviceNotice);
                }


            }
        }

        return new ResponseWithData<>().msg("操作成功").code(200);

    }

    @Override
    public ResponseWithData<?> checkAccoutFse(Long ServiceNoticeId) {
        ServiceNotice serviceNotice = serviceNoticeMapper.selectServiceNoticeById(ServiceNoticeId);
        if (serviceNotice != null && StringUtils.isNotEmpty(serviceNotice.getAccoutfseId())) {
            return new ResponseWithData<>().success(true).msg("查询成功").code(200);
        }
        return new ResponseWithData<>().success(false).msg("查询成功").code(200);
    }

    @Override
    public ResponseWithData<?> checkAddressDistance(String ServiceNoticeId, String longitude, String latitude) {
        // 查询仪器原有经纬度
        List<InstrumentInfo> list = instrumentInfoMapper.getInstrumentInfoList(ServiceNoticeId);
        if (list != null && list.size() > 0 && list.get(0) != null) {
            // 签到时获取的定位经纬度
            LngLat start = new LngLat(Double.parseDouble(longitude), Double.parseDouble(latitude));

            // 获取仪器之前数据库中存的经纬度
            LngLat end = new LngLat(list.get(0).getLongitude(), list.get(0).getLatitude());

            // 计算获取两组经纬度的距离 取公里KM
            double actualDistance = AMapUtils.calculateLineDistance(start, end) / 1000;

            // 查询距离参数
            Configuration configuration = new Configuration();
            configuration.setName("address_update");
            List<Configuration> cList = configurationMapper.selectConfigurationList(configuration);
            double configureDistance = Double.parseDouble(cList.get(0).getValue());

            // 比对距离参数与实际距离的大小 如果实际距离大于距离参数则需触发地址变更
            if (actualDistance > configureDistance) {
                return new ResponseWithData<>().success(true).msg("触发地址变更").code(200);
            }

        }
        return new ResponseWithData<>().success(false).msg("不触发地址变更").code(200);
    }

    @Override
    public ResponseWithData<?> getInstrument(String ServiceNoticeId) {
        List<InstrumentInfo> list = instrumentInfoMapper.getInstrumentInfoList(ServiceNoticeId);
        return new ResponseWithData<>().success(list).msg("查询成功").code(200);
    }

    @Override
    public ResponseWithData<?> updateInstrument(String ServiceNoticeIds, Double longitude, Double latitude) {
        String[] sids = ServiceNoticeIds.split(",");
        for (int i = 0; i < sids.length; i++) {
            List<InstrumentInfo> list = instrumentInfoMapper.getInstrumentInfoList(sids[i]);
            InstrumentInfo instrumentInfo = new InstrumentInfo();
            instrumentInfo.setId(list.get(0).getId());
            instrumentInfo.setLongitude(longitude);
            instrumentInfo.setLatitude(latitude);
            instrumentInfoMapper.updateInstrumentInfo(instrumentInfo);
        }

        return new ResponseWithData<>().success().msg("更新成功").code(200);
    }

    @Override
    public List<JSONObject> getInstrumentByServiceNo(Map<String, Object> params) {
        List<JSONObject> list = serviceInstrumentMapper.getInstrumentByServiceNo(params);
        return list;
    }

    @Override
    public ResponseWithData<?> bingQrCode(InstrumentInfo instrumentInfo) throws Exception {
        /** 调用CC端仪2.17绑定仪器条码接口 */
        JSONObject jsonObject = ccService.BindDeviceInfo(instrumentInfo.getInstrumentId(), instrumentInfo.getAccoutfseId(), instrumentInfo.getQrCode());

        // 需要验证接口返回是否成功，如果成功更新数据库

        if ("200".equals(jsonObject.getString("code"))) {
            InstrumentInfo iif = new InstrumentInfo();
            iif.setInstrumentId(instrumentInfo.getInstrumentId());
            List<InstrumentInfo> iifList = instrumentInfoMapper.selectInstrumentInfoList(iif);

            instrumentInfo.setAccoutfseId(null);
            instrumentInfo.setAccoutfseName(null);

            if (iifList != null && iifList.size() > 0) {
                instrumentInfo.setId(iifList.get(0).getId());
                instrumentInfo.setUpdateTime(new Date());
                instrumentInfoMapper.updateInstrumentInfo(instrumentInfo);
            } else {
                instrumentInfo.setCreateTime(new Date());
                /** 调用高德地理解析接口，根据地址解析经纬度 */
                Map<String, String> map = locationService.AddressResolution(instrumentInfo.getInstAddress(), "");
                if (map != null && map.size() == 2) {
                    instrumentInfo.setLongitude(Double.parseDouble(map.get("longitude")));
                    instrumentInfo.setLatitude(Double.parseDouble(map.get("latitude")));
                }
                instrumentInfoMapper.insertInstrumentInfo(instrumentInfo);
            }
            return new ResponseWithData<>().success().msg(jsonObject.getString("msg")).code(200);
        } else {
            return new ResponseWithData<>().success().msg(jsonObject.getString("msg")).code(202);
        }
    }

    /**
     * 2.54查询服务报告数据
     *
     * @methodName: syncAllServiceReport
     * @description: TODO
     * @return: com.ruoyi.system.api.ResponseWithData<?>
     * @author: wlf
     * @date: 2020-04-24 16:51
     **/
    @Override
    public ResponseWithData<?> syncAllServiceReport(String instrument_id, String starttime, String endtime, String custName, String snType, String snSubType, String serialNo, String status) {
        return ccService.syncAllServiceReport(instrument_id, starttime, endtime, custName, snType, snSubType, serialNo, status);
    }

    @Override
    public String getInstrumentCfda(String instrumentCode) {
        String ccServerUrl = global.getCcServerUrl();

        StringBuffer url = new StringBuffer();
        url.append(ccServerUrl);
        url.append("getInstrumentCFDA.asmx/getInstrumentCFDAHandle");

        String postParam = "InstrumentCode=" + instrumentCode;
        Map<String, String> resultMap = pokeRequestServe.transPostJD(url.toString(), "获取设备cfda", "getInstrumentCFDAHandle", postParam);
        Integer code = Integer.parseInt(resultMap.get("code"));
        String cfda = "";
        if (code == 200) {
            // 调用成功
            String body = resultMap.get("responseBody");
            JSONObject obj = JSON.parseObject(body);
            if ("1".equals(obj.getString("status"))) {

                /** 获取CC端 */
                JSONArray jsonArray = obj.getJSONArray("record");
                if (jsonArray != null && jsonArray.size() > 0) {
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        cfda = jsonObject.getString("CFDA");
                    }
                }
            }
        }
        return  cfda;
    }
}
